Retirado do artigo Miller et al. (2019). Distance sampling in R. Journal of Statistical Sofware 89(1)

Formatação do conjunto de dados

Variáveis necessárias para o data.frame:

Transectos que foram amostrados, mas que não tiveram observações (n = 0) devem ser incluídos no conjunto de dados com NA nas observações de distância e qualquer outra covariael para a qual não se tenha observação.

# cutia_tap_arap |> 
#   complete(Region.Label, Sample.Label, sp_name) |> 
#   datatable(filter = list(position = "top"))

Jogar a imputacao de NAs pra dentro da funcao carregar dados completos.

Determinando a distância para truncar os dados

# desenha o grafico com a distribuicao de distancias perpendiculares
cutia_tap_arap |> 
  plotar_distribuicao_distancia_interativo()
Warning: Continuous y aesthetic
ℹ did you forget `aes(group = ...)`?

Ajustando funções de detecção no R

Cutias da Resex Tapajós-Arapiuns

Ajustando um modelo ao dados das cutias Dsyprocta croconota, configurando uma distância limite de 20m e usando Half-normal como key function usando o argumento key.

# ajustando a função de detecção para uma distancia de truncamento de 20 metros
# Key function - Half-normal 
cutia_hn <- cutia_tap_arap |> 
#  filter(Region.Label != "Pascoal") |> 
  ds(
    truncation = 20,
    key = "hn"
  )
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 7227.642
Fitting half-normal key function with cosine(2) adjustments
AIC= 7207.469
Fitting half-normal key function with cosine(2,3) adjustments
AIC= 7201.248
Fitting half-normal key function with cosine(2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 7152.177
Fitting half-normal key function with cosine(2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 7146.681
Fitting half-normal key function with cosine(2,3,4,5,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 7129.428
Warning: Detection function is not strictly monotonic!Error in create.varstructure(model, region.table, sample.table, obs.table,  : 
  Following regions have no samples -  Pascoal

Ajustando um modelo ao dados da cutia Dsyprocta croconota, configurando uma distância limite de 20m e usando Hazard rate como key function usando o argumento key.

# Key function - Hazard-rate 
cutia_hr <- cutia_tap_arap |> 
  filter(Region.Label != "Pascoal") |> 
  ds(
    truncation = 20,
     key = "hr"
  )
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 5246.759
Fitting hazard-rate key function with cosine(2) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Some observations not included in the analysis
plot(cutia_hn)

plot(cutia_hr)

Ajustando um modelo ao dados das cutias, configurando uma distância limite de 20m e usando Uniform como key function a séria de ajuste com o argumento adjustment ee especificando a ordem com o argumento order.

cutia_unifcos <- cutia_tap_arap |> 
  ds(truncation = 20,
     key = "unif",
     adjustment = "cos",
     order = c(1, 2))

Ajuste Hermite pollynomial usa od código "herm" e polinomial simples "poly".

Podemos incluir covariáveis utilizando o argumento formula = ~ .... Abaixo, está especificado um modelo “Hazard-rate” para os dados de cutia q ue inclui o tempo de senso como covariável e uma distância limite de 20m.

cutia_hr_time <- cutia_tap_arap_15 |> 
  ds(truncation = 20,
     key = "hr",
     formula = ~ cense_time)

Adicionando uma segunda covariável: tamanho do grupo.

cutia_hr_time_size <- ds(data = cutia_tap_arap_15,
                     truncation = 20,
                     transect = "line",
                     key = "hr",
                     formula = ~ cense_time + size)
plot(cutia_hr_time)
plot(cutia_hr_time_size)

Checagem e seleção de modelos

Podemos usar a função summary para obter informações importantes sobre o modelo.

summary(cutia_hn)

O resultado inclui detalhes sobre o dado e a especificação do modelo, assim como dos coeficientes (\(\beta_{j}\)) e sua inceteza, a média do valor de detectabilidade e sua incerteza e uma estimativa da abundância na área coberta pela amostragem (sem levar em consideração o tamanho dos agrupamentos, ou bandos).

Bondade de ajuste

Para visualizar quão bem a função de detecção se ajusta aos dados quanto temos as distâncias exatas podemos usar um plot de quantis empíricos x teóricos (Q-Q plot). Ele compara a função de distribuição cumulativa (CDF) dos valores ajustados da função detecção a distribuição empírica dos dados (EDF).

Também podemos usar o teste de Cramér-von Mises para testar se os pontos da EDF e da CDF tem origem na mesma distribuição. O teste usa a soma de todas as distâncias entre um ponto e a linha y = x para formar a estatística a ser testada. Um resultado significativo fornece evidência contra a hiipótese nula, sugerindo que o modelo não se ajusta bem aos dados.

# ajustando um modelo Half-normal
cutia_hn <- ds(data = cutia_tap_arap_15,
                 truncation = 20,
                 transect = "line",
                 key = "hn", 
                 adjustment = NULL)

# conduzindo o teste dfe bondadede ajuste de Cramer-von Mises
gof_ds(cutia_hn)

gof_ds(cutia_hr_time)

O resutlado do teste aponta que o modelo Half-normal deve ser descartado.

Testes de bondade de ajuste de chi-quadrado são gerados usando a função gof_ds quando as distâncias forneceidas estão categorizadas.

Seleção de Modelos

Uma vez que temos um conjunto de modelos plausíveis, podemos utilizar o cirtériode informaçãode Akaike (AIC) para selecionar entre os modelos o que melhor se ajusta aos dados utilizando a função summarize_ds_models.

# gerando uma tabela de seleção de modelos usando AIC
summarize_ds_models(cutia_hn, cutia_hr_time, cutia_hr_time_size)

O melhor modelo é o Hazard-rate com tempo de senso e tamanho do grupo como covariáveis.

Estimando a abundância e a variância

Estimando abundância e variância no R

Para obter a abundância na região de estudo, primeiro calculamos a abundância na área amostrada para obter \(N_c\) e em seguida escalonamos esse valor para toda a área de estudo multiplicando \(N_c\) pela razão entre a área amostrada e a área da região. Para estimar a abundância na área amostrada, utilizamos as estimativas de probabilidade de detecção no estimador de Horvitz-Thompson.

Quando fornecemos os dados no formato correto (“flatfile”) ds irá automaticamente calcular as estimativas de abundância baseado nas informações de amostragem presenta nos dados.

summary(cutia_hn)
  1. Summary statistics: fornece as áreas, aŕea de amostragem, esforço, número de observações, número de transectos, taxa de encontro, seus erros padrões e coeficientes de variação para cada estrato;

  2. Abundance: fornece estimativas, erros padrões, coeficientesde variação, intervalos de confiança inferior e superior, graus de liberdade para a estimativa de abundância de cada estrato;

  3. Densidade: lista as mesmas estatísticas de Abundance, só que para densidade.

LS0tCnRpdGxlOiAiRGlzdGFuY2Ugbm8gUiBjb20gZGFkb3MgJ21vZGVsbyciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClJldGlyYWRvIGRvIGFydGlnbyBNaWxsZXIgZXQgYWwuICgyMDE5KS4gRGlzdGFuY2Ugc2FtcGxpbmcgaW4gUi4gSm91cm5hbCBvZiBTdGF0aXN0aWNhbCBTb2Z3YXJlIDg5KDEpCgpgYGB7ciBzZXR1cH0KIyBpbnN0YWxhciBwYWNvdGVzIG5lY2Vzc8OhcmlvcwojaW5zdGFsbC5wYWNrYWdlcygiRGlzdGFuY2UiKQoKIyBpbnN0YWxhciBwYWNvdGVzIGFkaWNpb25haXMKI2luc3RhbGwucGFja2FnZXMoIm1yZHMiKQojaW5zdGFsbC5wYWNrYWdlcygiZHNtIikKI2luc3RhbGwucGFja2FnZXMoIm1hZHMiKQojaW5zdGFsbC5wYWNrYWdlcygiZHNpbXMiKQoKIyBjYXJyZWdhciBwYWNvdGVzIApsaWJyYXJ5KERpc3RhbmNlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KERUKQpsaWJyYXJ5KGZsZXh0YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHlyKQoKIyBjYXJyZWdhciBhcyBmdW7Dp8O1ZXMgZGEgcGFzdGEgUgojIGNhcnJlZ2FyIGZ1bsOnw6NvIHNjcmlwdF9jYXJyZWdhcl9mdW7Dp8O1ZXNfcGFzdGFfci5SCnNvdXJjZSgKICBwYXN0ZTAoCiAgICBoZXJlOjpoZXJlKCksCiAgICAiL1IvbWluaGFzX2Z1bmNvZXMuUiIKICApCikKCiMgY2FycmVnYXIgZGFkb3MKY3V0aWFfdGFwX2FyYXAgPC0gdHJhbnNmb3JtYXJfcGFyYV9kaXN0YW5jZVJfY292YXJpYXZlaXMoKSB8PiAKICBmaWx0ZXIoCiAgICB1Y19uYW1lID09ICJSZXNleCBUYXBham9zLUFyYXBpdW5zIiwKICAgIHNwX25hbWUgPT0gIkRhc3lwcm9jdGEgY3JvY29ub3RhIgogICkgfD4gCiAgZHJvcF9uYShkaXN0YW5jZSkKICAKI3JlYWRyOjp3cml0ZV9yZHMoY3V0aWFfdGFwX2FyYXAsICMiL2hvbWUvdXN1YXJpby9Eb2N1bWVudG9zL1ZpdG9yL1BpcGVyM0QvV1dGL01vbml0b3JhL0RhZG9zL2RhdGEvY3V0aWFfdGFwX2FyYXAucmRzIikKY3V0aWFfdGFwX2FyYXAgfD4gCiAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSAidG9wIikKYGBgCgojIEZvcm1hdGHDp8OjbyBkbyBjb25qdW50byBkZSBkYWRvcwoKVmFyacOhdmVpcyBuZWNlc3PDoXJpYXMgcGFyYSBvIGBkYXRhLmZyYW1lYDoKCi0gYFJlZ2lvbi5MYWJlbGA6IHZldG9yIGZhdG9yIGNvbSBvIGVzdHJhdG8gY29udGVuZG8gbyB0cmFuc2VjdG8gKHBvZGUgc2VyIHVtYSBlc3RyYXRpZmljYcOnw6NvIHByw6ktYW1vc3RyYWdlbSAtIFVDcyAtIG91IHDDs3MtYW1vc3RyYWdlbSAtIGV4LiByZWdpw6NvLCBlc3RhZG8sIGJpb21hKQoKLSBgQXJlYWA6IHZldG9yIG51bcOpcmljbyBjb250ZW5kbyBhIMOhcmVhIGRvIGVzdHJhdG87CgotIGBTYW1wbGUuTGFiZWxgOiB2ZXRvciBuw7ptZXJpY28gY29udGVuZG8gYSBpZGVudGlkYWRlIChJRCkgZG8gdHJhbnNlY3RvCgotIGBvYmplY3RgOiBub21lIGFkaWNpb25hbCwgdmVyIHNlw6fDo28gNjsKCi0gYGRldGVjdGVkYDogbm9tZSBhZGljaW9uYWwsIHZlciBzZcOnw6NvIDY7CgotIGBFZmZvcnRgOiB2ZXRvciBuw7ptZXJpY28gY29udGVuZG8gbyBlc2ZvcsOnbyBkbyB0cmFuc2VjdG8gKHBhcmEgbGluaGFzIHNldSBjb21wcmltZW50bywgcGFyYSBwb250b3MgbyBuw7ptZXJvIGRlIHZlemVzIHF1ZSBvIHBvbnRvIGZvaSB2aXNpdGFkbykKCi0gYHNpemVgOiB2ZXRvciBudW3DqXJpY28gY29wbnRlbmRvIG8gdGFtYW5obyBkbyBncnVwbyBvYnNlcnZhZG87CgotIGBkaXN0YW5jZWA6IHZldG9yIG51bcOpcmljbyBkZSBkaXN0w6JuY2lhcyBvYnNlcnZhZGFzOwoKLSBgTW9udGhgOgoKLSBgT0JzYDoKCi0gYFNwYDoKCiAtIGBtYXNgOgogCiAtIGBIQVNgOgogCiAtIGBTdHVkeS5BcmVhYDoKIApUcmFuc2VjdG9zIHF1ZSBmb3JhbSBhbW9zdHJhZG9zLCBtYXMgcXVlIG7Do28gdGl2ZXJhbSBvYnNlcnZhw6fDtWVzIChuID0gMCkgZGV2ZW0gc2VyIGluY2x1w61kb3Mgbm8gY29uanVudG8gZGUgZGFkb3MgY29tIGBOQWAgbmFzIG9ic2VydmHDp8O1ZXMgZGUgZGlzdMOibmNpYSBlIHF1YWxxdWVyIG91dHJhIGNvdmFyaWFlbCBwYXJhIGEgcXVhbCBuw6NvIHNlIHRlbmhhIG9ic2VydmHDp8Ojby4KIApgYGB7cn0KIyBjdXRpYV90YXBfYXJhcCB8PiAKIyAgIGNvbXBsZXRlKFJlZ2lvbi5MYWJlbCwgU2FtcGxlLkxhYmVsLCBzcF9uYW1lKSB8PiAKIyAgIGRhdGF0YWJsZShmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIpKQpgYGAKCkpvZ2FyIGEgaW1wdXRhY2FvIGRlIGBOQWBzIHByYSBkZW50cm8gZGEgZnVuY2FvIGNhcnJlZ2FyIGRhZG9zIGNvbXBsZXRvcy4KCiMjIERldGVybWluYW5kbyBhIGRpc3TDom5jaWEgcGFyYSB0cnVuY2FyIG9zIGRhZG9zCgpgYGB7ciwgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTEwLCB3YXJuaW5nPUZBTFNFfQojIGRlc2VuaGEgbyBncmFmaWNvIGNvbSBhIGRpc3RyaWJ1aWNhbyBkZSBkaXN0YW5jaWFzIHBlcnBlbmRpY3VsYXJlcwpjdXRpYV90YXBfYXJhcCB8PiAKICBwbG90YXJfZGlzdHJpYnVpY2FvX2Rpc3RhbmNpYV9pbnRlcmF0aXZvKCkKYGBgCgogCiMjIEFqdXN0YW5kbyBmdW7Dp8O1ZXMgZGUgZGV0ZWPDp8OjbyBubyBSCgojIyMgQ3V0aWFzIGRhIFJlc2V4IFRhcGFqw7NzLUFyYXBpdW5zCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhcyBjdXRpYXMgKkRzeXByb2N0YSBjcm9jb25vdGEqLCBjb25maWd1cmFuZG8gdW1hIGRpc3TDom5jaWEgbGltaXRlIGRlIDIwbSBlIHVzYW5kbyAqSGFsZi1ub3JtYWwqIGNvbW8gKmtleSBmdW5jdGlvbiogdXNhbmRvIG8gYXJndW1lbnRvIGBrZXlgLgoKYGBge3J9CiMgYWp1c3RhbmRvIGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBwYXJhIHVtYSBkaXN0YW5jaWEgZGUgdHJ1bmNhbWVudG8gZGUgMjAgbWV0cm9zCiMgS2V5IGZ1bmN0aW9uIC0gSGFsZi1ub3JtYWwgCmN1dGlhX2huIDwtIGN1dGlhX3RhcF9hcmFwIHw+IAojICBmaWx0ZXIoUmVnaW9uLkxhYmVsICE9ICJQYXNjb2FsIikgfD4gCiAgZHMoCiAgICB0cnVuY2F0aW9uID0gMjAsCiAgICBrZXkgPSAiaG4iCiAgKQpgYGAKCkFqdXN0YW5kbyB1bSBtb2RlbG8gYW8gZGFkb3MgZGEgY3V0aWEgKkRzeXByb2N0YSBjcm9jb25vdGEqLCBjb25maWd1cmFuZG8gdW1hIGRpc3TDom5jaWEgbGltaXRlIGRlIDIwbSBlIHVzYW5kbyAqSGF6YXJkIHJhdGUqIGNvbW8gKmtleSBmdW5jdGlvbiogdXNhbmRvIG8gYXJndW1lbnRvIGBrZXlgLgoKYGBge3J9CiMgS2V5IGZ1bmN0aW9uIC0gSGF6YXJkLXJhdGUgCmN1dGlhX2hyIDwtIGN1dGlhX3RhcF9hcmFwIHw+IAogIGZpbHRlcihSZWdpb24uTGFiZWwgIT0gIlBhc2NvYWwiKSB8PiAKICBkcygKICAgIHRydW5jYXRpb24gPSAyMCwKICAgICBrZXkgPSAiaHIiCiAgKQpgYGAKCgpgYGB7cn0KcGxvdChjdXRpYV9obikKcGxvdChjdXRpYV9ocikKYGBgCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhcyBjdXRpYXMsIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpVbmlmb3JtKiBjb21vICprZXkgZnVuY3Rpb24qIGEgc8OpcmlhIGRlIGFqdXN0ZSBjb20gbyBhcmd1bWVudG8gYGFkanVzdG1lbnRgIGVlIGVzcGVjaWZpY2FuZG8gYSBvcmRlbSBjb20gbyBhcmd1bWVudG8gYG9yZGVyYC4KCmBgYHtyfQpjdXRpYV91bmlmY29zIDwtIGN1dGlhX3RhcF9hcmFwIHw+IAogIGRzKHRydW5jYXRpb24gPSAyMCwKICAgICBrZXkgPSAidW5pZiIsCiAgICAgYWRqdXN0bWVudCA9ICJjb3MiLAogICAgIG9yZGVyID0gYygxLCAyKSkKYGBgCgpBanVzdGUgKkhlcm1pdGUgcG9sbHlub21pYWwqIHVzYSBvZCBjw7NkaWdvIGAiaGVybSJgIGUgcG9saW5vbWlhbCBzaW1wbGVzIGAicG9seSJgLgoKUG9kZW1vcyBpbmNsdWlyIGNvdmFyacOhdmVpcyB1dGlsaXphbmRvIG8gYXJndW1lbnRvIGBmb3JtdWxhID0gfiAuLi5gLiBBYmFpeG8sIGVzdMOhIGVzcGVjaWZpY2FkbyB1bSBtb2RlbG8gIkhhemFyZC1yYXRlIiBwYXJhIG9zIGRhZG9zIGRlIGN1dGlhIHEgdWUgaW5jbHVpIG8gdGVtcG8gZGUgc2Vuc28gY29tbyBjb3ZhcmnDoXZlbCBlIHVtYSBkaXN0w6JuY2lhIGxpbWl0ZSBkZSAyMG0uCgpgYGB7cn0KY3V0aWFfaHJfdGltZSA8LSBjdXRpYV90YXBfYXJhcF8xNSB8PiAKICBkcyh0cnVuY2F0aW9uID0gMjAsCiAgICAga2V5ID0gImhyIiwKICAgICBmb3JtdWxhID0gfiBjZW5zZV90aW1lKQpgYGAKCkFkaWNpb25hbmRvIHVtYSBzZWd1bmRhIGNvdmFyacOhdmVsOiB0YW1hbmhvIGRvIGdydXBvLgoKYGBge3J9CmN1dGlhX2hyX3RpbWVfc2l6ZSA8LSBkcyhkYXRhID0gY3V0aWFfdGFwX2FyYXBfMTUsCiAgICAgICAgICAgICAgICAgICAgIHRydW5jYXRpb24gPSAyMCwKICAgICAgICAgICAgICAgICAgICAgdHJhbnNlY3QgPSAibGluZSIsCiAgICAgICAgICAgICAgICAgICAgIGtleSA9ICJociIsCiAgICAgICAgICAgICAgICAgICAgIGZvcm11bGEgPSB+IGNlbnNlX3RpbWUgKyBzaXplKQpgYGAKCmBgYHtyfQpwbG90KGN1dGlhX2hyX3RpbWUpCnBsb3QoY3V0aWFfaHJfdGltZV9zaXplKQpgYGAKCiMjIENoZWNhZ2VtIGUgc2VsZcOnw6NvIGRlIG1vZGVsb3MKClBvZGVtb3MgdXNhciBhIGZ1bsOnw6NvIGBzdW1tYXJ5YCBwYXJhIG9idGVyIGluZm9ybWHDp8O1ZXMgaW1wb3J0YW50ZXMgc29icmUgbyBtb2RlbG8uCgpgYGB7cn0Kc3VtbWFyeShjdXRpYV9obikKYGBgCgpPIHJlc3VsdGFkbyAgaW5jbHVpIGRldGFsaGVzIHNvYnJlIG8gZGFkbyBlIGEgZXNwZWNpZmljYcOnw6NvIGRvIG1vZGVsbywgYXNzaW0gY29tbyBkb3MgY29lZmljaWVudGVzICgkXGJldGFfe2p9JCkgZSBzdWEgaW5jZXRlemEsIGEgbcOpZGlhIGRvIHZhbG9yIGRlIGRldGVjdGFiaWxpZGFkZSBlIHN1YSBpbmNlcnRlemEgZSB1bWEgZXN0aW1hdGl2YSBkYSBhYnVuZMOibmNpYSBuYSDDoXJlYSBjb2JlcnRhIHBlbGEgYW1vc3RyYWdlbSAoc2VtIGxldmFyIGVtIGNvbnNpZGVyYcOnw6NvIG8gdGFtYW5obyBkb3MgYWdydXBhbWVudG9zLCBvdSBiYW5kb3MpLiAKCiMjIyBCb25kYWRlIGRlIGFqdXN0ZQoKUGFyYSB2aXN1YWxpemFyIHF1w6NvIGJlbSBhIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gc2UgYWp1c3RhIGFvcyBkYWRvcyBxdWFudG8gdGVtb3MgYXMgZGlzdMOibmNpYXMgZXhhdGFzIHBvZGVtb3MgdXNhciB1bSBwbG90IGRlIHF1YW50aXMgZW1ww61yaWNvcyB4IHRlw7NyaWNvcyAoUS1RIHBsb3QpLiBFbGUgY29tcGFyYSBhIGZ1bsOnw6NvIGRlIGRpc3RyaWJ1acOnw6NvIGN1bXVsYXRpdmEgKENERikgZG9zIHZhbG9yZXMgYWp1c3RhZG9zIGRhIGZ1bsOnw6NvIGRldGVjw6fDo28gYSBkaXN0cmlidWnDp8OjbyBlbXDDrXJpY2EgZG9zIGRhZG9zIChFREYpLiAKClRhbWLDqW0gcG9kZW1vcyB1c2FyIG8gdGVzdGUgZGUgQ3JhbcOpci12b24gTWlzZXMgcGFyYSB0ZXN0YXIgc2Ugb3MgcG9udG9zIGRhIEVERiBlIGRhIENERiB0ZW0gb3JpZ2VtIG5hIG1lc21hIGRpc3RyaWJ1acOnw6NvLiBPIHRlc3RlIHVzYSBhIHNvbWEgZGUgdG9kYXMgYXMgZGlzdMOibmNpYXMgZW50cmUgdW0gcG9udG8gZSBhIGxpbmhhIHkgPSB4IHBhcmEgZm9ybWFyIGEgZXN0YXTDrXN0aWNhIGEgc2VyIHRlc3RhZGEuIFVtIHJlc3VsdGFkbyBzaWduaWZpY2F0aXZvIGZvcm5lY2UgZXZpZMOqbmNpYSBjb250cmEgYSBoaWlww7N0ZXNlIG51bGEsIHN1Z2VyaW5kbyBxdWUgbyBtb2RlbG8gbsOjbyBzZSBhanVzdGEgYmVtIGFvcyBkYWRvcy4KCmBgYHtyfQojIGFqdXN0YW5kbyB1bSBtb2RlbG8gSGFsZi1ub3JtYWwKY3V0aWFfaG4gPC0gZHMoZGF0YSA9IGN1dGlhX3RhcF9hcmFwXzE1LAogICAgICAgICAgICAgICAgIHRydW5jYXRpb24gPSAyMCwKICAgICAgICAgICAgICAgICB0cmFuc2VjdCA9ICJsaW5lIiwKICAgICAgICAgICAgICAgICBrZXkgPSAiaG4iLCAKICAgICAgICAgICAgICAgICBhZGp1c3RtZW50ID0gTlVMTCkKCiMgY29uZHV6aW5kbyBvIHRlc3RlIGRmZSBib25kYWRlZGUgYWp1c3RlIGRlIENyYW1lci12b24gTWlzZXMKZ29mX2RzKGN1dGlhX2huKQoKZ29mX2RzKGN1dGlhX2hyX3RpbWUpCmBgYAoKTyByZXN1dGxhZG8gZG8gdGVzdGUgYXBvbnRhIHF1ZSBvIG1vZGVsbyAqSGFsZi1ub3JtYWwqIGRldmUgc2VyIGRlc2NhcnRhZG8uCgpUZXN0ZXMgZGUgYm9uZGFkZSBkZSBhanVzdGUgZGUgY2hpLXF1YWRyYWRvIHPDo28gZ2VyYWRvcyB1c2FuZG8gYSBmdW7Dp8OjbyBgZ29mX2RzYCBxdWFuZG8gYXMgZGlzdMOibmNpYXMgZm9ybmVjZWlkYXMgZXN0w6NvIGNhdGVnb3JpemFkYXMuCgojIyMgU2VsZcOnw6NvIGRlIE1vZGVsb3MKClVtYSB2ZXogcXVlIHRlbW9zIHVtIGNvbmp1bnRvIGRlIG1vZGVsb3MgcGxhdXPDrXZlaXMsIHBvZGVtb3MgdXRpbGl6YXIgbyBjaXJ0w6lyaW9kZSBpbmZvcm1hw6fDo29kZSBBa2Fpa2UgKEFJQykgcGFyYSBzZWxlY2lvbmFyIGVudHJlIG9zIG1vZGVsb3MgbyBxdWUgbWVsaG9yIHNlIGFqdXN0YSBhb3MgZGFkb3MgdXRpbGl6YW5kbyBhIGZ1bsOnw6NvIGBzdW1tYXJpemVfZHNfbW9kZWxzYC4KCmBgYHtyfQojIGdlcmFuZG8gdW1hIHRhYmVsYSBkZSBzZWxlw6fDo28gZGUgbW9kZWxvcyB1c2FuZG8gQUlDCnN1bW1hcml6ZV9kc19tb2RlbHMoY3V0aWFfaG4sIGN1dGlhX2hyX3RpbWUsIGN1dGlhX2hyX3RpbWVfc2l6ZSkKYGBgCgpPIG1lbGhvciBtb2RlbG8gw6kgbyBIYXphcmQtcmF0ZSBjb20gdGVtcG8gZGUgc2Vuc28gZSB0YW1hbmhvIGRvIGdydXBvIGNvbW8gY292YXJpw6F2ZWlzLgoKIyMgRXN0aW1hbmRvIGEgYWJ1bmTDom5jaWEgZSBhIHZhcmnDom5jaWEKCiMjIyBFc3RpbWFuZG8gYWJ1bmTDom5jaWEgZSB2YXJpw6JuY2lhIG5vIFIKClBhcmEgb2J0ZXIgYSBhYnVuZMOibmNpYSBuYSByZWdpw6NvIGRlIGVzdHVkbywgcHJpbWVpcm8gY2FsY3VsYW1vcyBhIGFidW5kw6JuY2lhIG5hIMOhcmVhIGFtb3N0cmFkYSBwYXJhIG9idGVyICROX2MkIGUgZW0gc2VndWlkYSBlc2NhbG9uYW1vcyBlc3NlIHZhbG9yIHBhcmEgdG9kYSBhIMOhcmVhIGRlIGVzdHVkbyBtdWx0aXBsaWNhbmRvICROX2MkIHBlbGEgcmF6w6NvIGVudHJlIGEgw6FyZWEgYW1vc3RyYWRhIGUgYSDDoXJlYSBkYSByZWdpw6NvLiBQYXJhIGVzdGltYXIgYSBhYnVuZMOibmNpYSBuYSDDoXJlYSBhbW9zdHJhZGEsIHV0aWxpemFtb3MgYXMgZXN0aW1hdGl2YXMgZGUgcHJvYmFiaWxpZGFkZSBkZSBkZXRlY8Onw6NvIG5vIGVzdGltYWRvciBkZSBIb3J2aXR6LVRob21wc29uLgoKUXVhbmRvIGZvcm5lY2Vtb3Mgb3MgZGFkb3Mgbm8gZm9ybWF0byBjb3JyZXRvICgiZmxhdGZpbGUiKSBgZHNgIGlyw6EgYXV0b21hdGljYW1lbnRlIGNhbGN1bGFyIGFzIGVzdGltYXRpdmFzIGRlIGFidW5kw6JuY2lhIGJhc2VhZG8gbmFzIGluZm9ybWHDp8O1ZXMgZGUgYW1vc3RyYWdlbSBwcmVzZW50YSBub3MgZGFkb3MuCgpgYGB7cn0Kc3VtbWFyeShjdXRpYV9obikKYGBgCgoxLiBTdW1tYXJ5IHN0YXRpc3RpY3M6IGZvcm5lY2UgYXMgw6FyZWFzLCBhxZVlYSBkZSBhbW9zdHJhZ2VtLCBlc2ZvcsOnbywgbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzLCBuw7ptZXJvIGRlIHRyYW5zZWN0b3MsIHRheGEgZGUgZW5jb250cm8sIHNldXMgZXJyb3MgcGFkcsO1ZXMgZSBjb2VmaWNpZW50ZXMgZGUgdmFyaWHDp8OjbyBwYXJhIGNhZGEgZXN0cmF0bzsKCjIuIEFidW5kYW5jZTogZm9ybmVjZSBlc3RpbWF0aXZhcywgZXJyb3MgcGFkcsO1ZXMsIGNvZWZpY2llbnRlc2RlIHZhcmlhw6fDo28sIGludGVydmFsb3MgZGUgY29uZmlhbsOnYSBpbmZlcmlvciBlIHN1cGVyaW9yLCBncmF1cyBkZSBsaWJlcmRhZGUgcGFyYSBhIGVzdGltYXRpdmEgZGUgYWJ1bmTDom5jaWEgZGUgY2FkYSBlc3RyYXRvOwoKMy4gRGVuc2lkYWRlOiBsaXN0YSBhcyBtZXNtYXMgZXN0YXTDrXN0aWNhcyBkZSBBYnVuZGFuY2UsIHPDsyBxdWUgcGFyYSBkZW5zaWRhZGUuCgo=